/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IMAGE_KNIFE_C_FILE_TYPE_UTIL_H
#define IMAGE_KNIFE_C_FILE_TYPE_UTIL_H

#include "imageknife_task.h"
#include <unordered_map>
#include <cstdint>
#include <vector>

namespace ImageKnifeC {

// 文件类型工具类
class FileTypeUtil {
public:
    // 判断文件是否为图像，并返回具体的图片类型
    ImageFormat CheckImageFormat(const uint8_t* data, size_t length)
    {
        const int expectedFilelength = 32;
        if (length < expectedFilelength) {
            length = expectedFilelength;
        }
        return GetFileType(data, length);
    }
private:
    // 文件签名映射表，key为 ImageFormat 枚举
    std::unordered_map<ImageFormat, std::vector<std::vector<uint8_t>>> fileSignatureMap_ = {
        {ImageFormat::JPG, {{0xFF, 0xD8}}}, // JPEG
        {ImageFormat::PNG, {{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}}}, // PNG
        {ImageFormat::GIF, {{0x47, 0x49, 0x46, 0x38, 0x39, 0x61}, {0x47, 0x49, 0x46, 0x38}}}, // GIF
        {ImageFormat::BMP, {{0x42, 0x4D}}}, // BMP
        {ImageFormat::SVG, {{0x3C, 0x3F, 0x78, 0x6D, 0x6C}, {0x3C, 0x73, 0x76, 0x67, 0x20}}}, // SVG
        {ImageFormat::WEBP, {{0x52, 0x49, 0x46, 0x46}}}, // WebP
        {ImageFormat::TIFF, {{0x49, 0x20, 0x49}, {0x49, 0x49, 0x2A, 0x00},
            {0x4D, 0x4D, 0x00, 0x2A}, {0x4D, 0x4D, 0x00, 0x2B}}}, // TIFF
        {ImageFormat::HEIC, {{0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70,
            0x68, 0x65, 0x69, 0x63, 0x00, 0x00, 0x00, 0x00},
            {0x00, 0x00, 0x00, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x68, 0x65, 0x69, 0x63, 0x00, 0x00, 0x00, 0x00}}}, // HEIC
        {ImageFormat::ICO, {{0x00, 0x00, 0x01, 0x00}}} // ICO 文件签名
    };

    // 获取文件类型
    ImageFormat GetFileType(const uint8_t* data, size_t length)
    {
        for (const auto& entry : fileSignatureMap_) {
            const ImageFormat fileType = entry.first;
            const std::vector<std::vector<uint8_t>>& signatures = entry.second;

            for (const auto& signature : signatures) {
                if (MatchesSignature(data, length, signature, fileType)) {
                    return fileType;
                }
            }
        }

        return ImageFormat::UNKNOWN; // 无法匹配的情况
    }

    // 检查文件头部魔数是否匹配
    bool MatchesSignature(const uint8_t* data, size_t length, const std::vector<uint8_t>& signature,
        ImageFormat fileType)
    {
        if (length < signature.size()) {
            return false; // 文件长度不足，无法匹配魔数
        }

        size_t offset = (fileType == ImageFormat::HEIC) ? 4 : 0;

        for (size_t i = offset; i < signature.size(); ++i) {
            if (data[i] != signature[i]) {
                return false; // 魔数不匹配
            }
        }
        return true; // 文件头部魔数匹配
    }
};
}
#endif // IMAGE_KNIFE_C_FILE_TYPE_UTIL_H
